package com.ssrs.framework.extend.plugin;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ssrs.framework.extend.ExtendActionConfig;
import com.ssrs.framework.extend.ExtendItemConfig;
import com.ssrs.framework.extend.ExtendPointConfig;
import com.ssrs.framework.extend.ExtendServiceConfig;
import com.ssrs.framework.extend.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 插件类，对应一个插件
 *
 * @author ssrs
 */
public class PluginConfig {
    private Map<String, ExtendPointConfig> extendPoints = new HashMap<String, ExtendPointConfig>();
    private Map<String, ExtendServiceConfig> extendServices = new HashMap<String, ExtendServiceConfig>();
    private Map<String, String> requiredExtendPoints = new HashMap<String, String>();
    private Map<String, String> requiredExtendServices = new HashMap<String, String>();
    private Map<String, ExtendActionConfig> extendActions = new HashMap<String, ExtendActionConfig>();
    private Map<String, ExtendItemConfig> extendItems = new HashMap<String, ExtendItemConfig>();
    private Map<String, String> requiredPlugins = new HashMap<String, String>();
    private String id;
    private String name;
    private String className;
    private String author;
    private String provider;
    private String version;
    private String description;
    private boolean enabled;
    private boolean running;

    public Map<String, ExtendPointConfig> getExtendPoints() {
        return extendPoints;
    }

    public Map<String, ExtendServiceConfig> getExtendServices() {
        return extendServices;
    }

    public Map<String, String> getRequiredExtendPoints() {
        return requiredExtendPoints;
    }


    public Map<String, ExtendActionConfig> getExtendActions() {
        return extendActions;
    }

    public Map<String, ExtendItemConfig> getExtendItems() {
        return extendItems;
    }


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getAuthor() {
        return author;
    }

    public String getVersion() {
        return version;
    }

    public String getDescription() {
        return description;
    }


    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabling) {
        this.enabled = enabling;
    }

    public boolean isRunning() {
        return running;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    public String getProvider() {
        return provider;
    }



    public void setAuthor(String author) {
        this.author = author;
    }

    public void setProvider(String provider) {
        this.provider = provider;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Map<String, String> getRequiredPlugins() {
        return requiredPlugins;
    }

    public void setRequiredPlugins(Map<String, String> requiredPlugins) {
        this.requiredPlugins = requiredPlugins;
    }

    @Override
    public String toString() {
        String str = super.toString();
        str = str.substring(str.lastIndexOf('@'));
        str = "plugin:" + getId() + str;
        return str;
    }

    public void parse(Class<?> pluginClass) throws PluginException {
        enabled = true;// 默认开启
        Plugin plugin = pluginClass.getAnnotation(Plugin.class);
        id = pluginClass.getName();
        name = plugin.name();
        className = pluginClass.getName();
        author = plugin.author();
        provider = plugin.provider();
        version = plugin.version();
        description = plugin.description();

        if (StrUtil.isEmpty(id)) {
            throw new PluginException("id is empty!");
        }
        if (StrUtil.isEmpty(name)) {
            throw new PluginException("name is empty!");
        }
        if (StrUtil.isEmpty(version)) {
            throw new PluginException("version is empty!");
        }


        // 插件依赖
        PluginRequired[] pluginRequireds = plugin.required();
        if (ObjectUtil.isNotNull(pluginRequireds)) {
            if (pluginRequireds.length > 0) {
                for (PluginRequired required : pluginRequireds) {
                    String requiredPlugin = required.required().getName();
                    String version = required.version();
                    requiredPlugins.put(requiredPlugin, version);
                }
            }
        }


        Set<Class<?>> extendPointClasses = ClassUtil.scanPackage(ClassUtil.getPackage(pluginClass), aClass -> aClass.isAnnotationPresent(ExtendPoint.class));
        // 扩展点
        if (CollUtil.isNotEmpty(extendPointClasses)) {
            for (Class<?> element : extendPointClasses) {
                ExtendPointConfig ep = new ExtendPointConfig();
                ep.init(this, element);
                extendPoints.put(ep.getId(), ep);
            }
        }

        // 扩展服务
        Set<Class<?>> extendServiceClasses = ClassUtil.scanPackage(ClassUtil.getPackage(pluginClass), aClass -> aClass.isAnnotationPresent(ExtendService.class));
        if (CollUtil.isNotEmpty(extendServiceClasses)) {
            for (Class<?> element : extendServiceClasses) {
                ExtendServiceConfig ep = new ExtendServiceConfig();
                ep.init(this, element);
                extendServices.put(ep.getId(), ep);
            }
        }

        // 扩展项
        Set<Class<?>> extendItemClasses = ClassUtil.scanPackage(ClassUtil.getPackage(pluginClass), aClass -> aClass.isAnnotationPresent(ExtendItem.class));
        if (CollUtil.isNotEmpty(extendItemClasses)) {
            for (Class<?> element : extendItemClasses) {
                ExtendItemConfig ei = new ExtendItemConfig();
                ei.init(this, element);
                extendItems.put(ei.getId(), ei);
                requiredExtendServices.put(ei.getExtendServiceId(), "Y");
            }
        }

        // 扩展行为
        Set<Class<?>> extendActionClasses = ClassUtil.scanPackage(ClassUtil.getPackage(pluginClass), aClass -> aClass.isAnnotationPresent(ExtendAction.class));
        if (CollUtil.isNotEmpty(extendActionClasses)) {
            for (Class<?> element : extendActionClasses) {
                ExtendActionConfig eac = new ExtendActionConfig();
                eac.init(this, element);
                extendActions.put(eac.getId(), eac);
                requiredExtendPoints.put(eac.getExtendPointId(), "Y");
            }
        }
    }
}
